// ***************************************************************************************
// Copyright (c) 2023-2025 Peng Cheng Laboratory
// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences
// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip
//
// iEDA is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
// See the Mulan PSL v2 for more details.
// ***************************************************************************************
/**
 * @File Name: contest_wrapper.cpp
 * @Brief :
 * @Author : Yell (12112088@qq.com)
 * @Version : 1.0
 * @Creat Date : 2023-09-15
 *
 */

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "contest_wrapper.h"

#include "IdbDesign.h"
#include "IdbLayout.h"
#include "contest_db.h"

#include "contest_row.h"
#include "contest_site.h"
#include "Point.hh"
#include "make_route.h"

namespace ieda_contest {

ContestWrapper::ContestWrapper(ContestDB* contest_db, idb::IdbLayout* idb_layout, idb::IdbDesign* idb_design)
{
  _contest_db = contest_db;
  _idb_layout = idb_layout;
  _idb_design = idb_design;
}

bool ContestWrapper::transfer_idb_to_contest()
{
  _contest_db->set_idb_design(_idb_design);
  _contest_db->set_idb_layout(_idb_layout);

  //启动STA
  auto* timing_engine = ista::TimingEngine::getOrCreateTimingEngine();

  idm::DataConfig& db_config = dmInst->get_config();
  vector<std::string> lib_files;
  if (db_config.get_lib_paths().size() > 0) {
    lib_files = db_config.get_lib_paths();
  }
    std::string sdc_file;
  if (!db_config.get_sdc_path().empty()) {
    sdc_file = db_config.get_sdc_path();
  }
  timing_engine->set_num_threads(50);
  timing_engine->readLiberty(lib_files);


  auto idb_adapter = std::make_unique<TimingIDBAdapter>(timing_engine->get_ista());
  idb_adapter->set_idb(dmInst->get_idb_builder());
  idb_adapter->convertDBToTimingNetlist();
  timing_engine->set_db_adapter(std::move(idb_adapter));
  if(!sdc_file.empty())
  {
    timing_engine->readSdc(sdc_file.c_str());
  }
  timing_engine->buildGraph();
  timing_engine->updateTiming();
  _contest_db->set_timing_engine(timing_engine);

  wrapContestNetList();
  wrapContestInstanceList();     
  wrapContestPinList();  
  completeConnection();
  wrapContestLayout();
  return true;
}

bool ContestWrapper::transfer_idb_to_evaluation()
{
  _contest_db->set_idb_design(_idb_design);
  _contest_db->set_idb_layout(_idb_layout);
  wrapContestNetList();
  wrapContestInstanceList_eva();     
  wrapContestPinList();  
  completeConnection();
  wrapContestLayout();
  return true;
}


void ContestWrapper::wrapContestInstanceList()
{  
  auto inst_list = _idb_design->get_instance_list()->get_instance_list();

  //////下面有问题
  for (auto* inst : inst_list) {
    auto name = inst->get_name();
    ContestInstance* p_inst = new ContestInstance(name);

    wrapContestInstance(inst, p_inst);

  auto db_adapter = _contest_db->get_timing_engine()->get_db_adapter();
  TimingIDBAdapter *idb_adapter = dynamic_cast<TimingIDBAdapter *>(db_adapter);
  auto ista_inst = idb_adapter->dbToSta(inst);
  bool isBufferCell = 0;
  if(!ista_inst) {
    isBufferCell = false;
  }else{
    isBufferCell = ista_inst->get_inst_cell()->isBuffer();
  }

  if (!p_inst->isMacro() && !p_inst->isBoundaryCell() && isBufferCell) {
        p_inst->set_type(ContestInstanceType::kBuffer);
  }
    _contest_db->_ContestInstance_list.push_back(p_inst);
    _contest_db->_ContestInstance_map.emplace(inst, p_inst);
    _contest_db->_Idbinstance_map.emplace(p_inst, inst);
  }
}

void ContestWrapper::wrapContestInstanceList_eva()
{  
  auto inst_list = _idb_design->get_instance_list()->get_instance_list();

  for (auto* inst : inst_list) {
    auto name = inst->get_name();
    ContestInstance* p_inst = new ContestInstance(name);

    wrapContestInstance(inst, p_inst);

    _contest_db->_ContestInstance_list.push_back(p_inst);
    _contest_db->_ContestInstance_map.emplace(inst, p_inst);
    _contest_db->_Idbinstance_map.emplace(p_inst, inst);
  }
}



void ContestWrapper::wrapContestInstance(idb::IdbInstance* inst, ContestInstance* ContestInst)
{
  ContestInst->set_width(inst->get_cell_master()->get_width());
  ContestInst->set_height(inst->get_cell_master()->get_height());
  
  // state
  if (inst->is_fixed()) {
    ContestInst->set_state(ContestInstanceState::kFixed);
  } else {
    ContestInst->set_state(ContestInstanceState::kPlaceable);
  }
  if (isBoundaryCell(inst)) {
  ContestInst->set_type(ContestInstanceType::kBoundaryCell);
  }

  // type
  if (inst->is_flip_flop()) {
    ContestInst->set_type(ContestInstanceType::kFlipFlop);
  } else if (inst->get_cell_master()->is_block()) {
    ContestInst->set_type(ContestInstanceType::kMacro);
  } else if (inst->get_cell_master()->is_logic()) {
    ContestInst->set_type(ContestInstanceType::kLogic);
  }else {
      ContestInst->set_type(ContestInstanceType::kNoInstanceType);
    }

  // coord
  ContestInst->set_lower_point(Point<int32_t>(inst->get_coordinate()->get_x(), inst->get_coordinate()->get_y()));
  ContestInst->set_upper_point(Point<int32_t>(inst->get_coordinate()->get_x() + inst->get_cell_master()->get_width(),
                                          inst->get_coordinate()->get_y() + inst->get_cell_master()->get_height()));
  ContestInst->set_anchor_center_point(Point<int32_t>(inst->get_coordinate()->get_x() + inst->get_cell_master()->get_width() / 2,
                                                  inst->get_coordinate()->get_y() + inst->get_cell_master()->get_height() / 2));
}


void ContestWrapper::wrapContestNetList()
{
  std::vector<IdbNet*> net_list = _idb_design->get_net_list()->get_net_list();

  for (auto* net : net_list) {
    auto name = net->get_net_name();
    ContestNet* p_net = new ContestNet(name);
    // ContestNet contest_net(name);

    wrapContestNet(net, p_net);

    // _contest_db->_net_list.push_back(contest_net);
    _contest_db->_ContestNet_list.push_back(p_net);
    
    _contest_db->_ContestNet_map.emplace(net, p_net);
    _contest_db->_net_map.emplace(p_net, net);
  }
}
void ContestWrapper::wrapContestNet(idb::IdbNet* net, ContestNet* ContestNet)
{
    ContestNet->set_Contestnet_weight(net->get_weight()); 

  // if (net->isDontCareNet()) {
  //   ContestNet->set_net_type(ContestNET_TYPE::kDontCare);
  // }

  if(net->is_clock())
  {
    ContestNet->set_net_type(ContestNET_TYPE::kClockNet);
  }
}
void ContestWrapper::wrapContestPinList()
{
  //TODO
  vector<idb::IdbPin*> pin_list;
  auto net_list =  _idb_design->get_net_list()->get_net_list();
  for(auto net : net_list)
  {
    pin_list.push_back(net->get_driving_pin());
    auto size = net->get_load_pins().size();
    for(int i = 0; i < size; i++)
    {
        pin_list.push_back(net->get_load_pins()[i]);
    }
  }
  if(!pin_list.empty()){
  for (auto* pin : pin_list) {
      if(pin == nullptr) continue;
    auto name = pin->get_pin_name();
    std::string pin_full_name;
    if (pin->get_instance()) {
      auto inst_name = pin->get_instance()->get_name();
      pin_full_name = inst_name + ":" + name;
    }else{
      pin_full_name = name;
    }

    ContestPin* p_pin = new ContestPin(pin_full_name);

    wrapContestPin(pin, p_pin);

    _contest_db->_ContestPin_list.push_back(p_pin);
    _contest_db->_ContestPin_map.emplace(pin, p_pin);
    _contest_db->_pin_map.emplace(p_pin, pin);
  }
  }

}
void ContestWrapper::wrapContestPin(idb::IdbPin* pin, ContestPin* ContestPin)
{
  // type
  if(pin ->is_primary_input()){
    ContestPin->set_pin_type(ContestPIN_TYPE::kPrimaryInput);
  }else if(pin->is_primary_output())
  {
    ContestPin->set_pin_type(ContestPIN_TYPE::kPrimaryOutput);
  }
  if(pin->get_term()->is_instance_pin())
  {
    if(pin->get_term()->get_direction() == IdbConnectDirection::kInput)
    {
      ContestPin->set_pin_type(ContestPIN_TYPE::kInstanceInput);
    }
    else if(pin->get_term()->get_direction() == IdbConnectDirection::kOutput)
    {
      ContestPin->set_pin_type(ContestPIN_TYPE::kInstanceOutput);
    }
    else if(pin->get_term()->get_direction() == IdbConnectDirection::kInOut)
    {
      ContestPin->set_pin_type(ContestPIN_TYPE::kInstanceInputOutput);
    }
  }
  if(pin->is_flip_flop_clk())
  {
    ContestPin->set_pin_type(ContestPIN_TYPE::kFlipFlopClk);
  }

  // coordi
  int32_t origin_offset_x = 0;
  int32_t origin_offset_y = 0;
  auto ipl_inst = pin->get_instance();
  if(!ipl_inst)
  {
    ContestPin->set_offset_coord(Point<int32_t>(origin_offset_x, origin_offset_y));
  }else{
    auto term_avg_position = pin->get_term()->get_average_position();
     origin_offset_x = term_avg_position.get_x() - ipl_inst->get_cell_master()->get_width() / 2;
     origin_offset_y = term_avg_position.get_y() - ipl_inst->get_cell_master()->get_height() / 2;

    int32_t modify_offset_x = 0;
    int32_t modify_offset_y = 0;

    idb::IdbOrient inst_orient = ipl_inst->get_orient();
    if (inst_orient == IdbOrient::kN_R0) {
      modify_offset_x = origin_offset_x;
      modify_offset_y = origin_offset_y;
    } else if (inst_orient == IdbOrient::kW_R90) {
      modify_offset_x = (-1) * origin_offset_y;
      modify_offset_y = origin_offset_x;
    } else if (inst_orient == IdbOrient::kS_R180) {
      modify_offset_x = (-1) * origin_offset_x;
      modify_offset_y = (-1) * origin_offset_y;
    } else if (inst_orient == IdbOrient::kFW_MX90) {
      modify_offset_x = origin_offset_y;
      modify_offset_y = origin_offset_x;
    } else if (inst_orient == IdbOrient::kFN_MY) {
      modify_offset_x = (-1) * origin_offset_x;
      modify_offset_y = origin_offset_y;
    } else if (inst_orient == IdbOrient::kFE_MY90) {
      modify_offset_x = (-1) * origin_offset_y;
      modify_offset_y = (-1) * origin_offset_x;
    } else if (inst_orient == IdbOrient::kFS_MX) {
      modify_offset_x = origin_offset_x;
      modify_offset_y = (-1) * origin_offset_y;
    } else if (inst_orient == IdbOrient::kE_R270) {
      modify_offset_x = origin_offset_y;
      modify_offset_y = (-1) * origin_offset_x;
    } else {
      LOG_WARNING << ipl_inst->get_name() + " has not the orient!";
    }
    ContestPin->set_offset_coord(Point<int32_t>(modify_offset_x, modify_offset_y));
  }
  ContestPin->set_coord(Point<int32_t>(pin->get_average_coordinate()->get_x(),pin->get_average_coordinate()->get_y()));
}


void ContestWrapper::wrapContestLayout()
{
  auto design_name = _idb_design->get_design_name();

  _contest_db->_ContestLayout = new ContestLayout(design_name);
  _contest_db->_ContestLayout->set_database_unit(_idb_layout->get_units()->get_micron_dbu());
  _contest_db->_ContestLayout->set_row_height(_idb_layout->get_rows()->get_row_height());
  _contest_db->_ContestLayout->set_site_width(_idb_layout->get_sites()->get_site_list()[0]->get_width());

///TODO
  // 更新die的点坐标
  auto die = _idb_layout->get_die();
  _contest_db->_ContestLayout->set_die_lower_point(Point<int32_t>(die->get_llx(), die->get_lly()));
  _contest_db->_ContestLayout->set_die_upper_point(Point<int32_t>(die->get_urx(), die->get_ury()));

  // 更新core的点坐标
  auto* idb_core = _idb_layout->get_core();
  IdbRect* idb_core_rect = idb_core->get_bounding_box();
  _contest_db->_ContestLayout->set_core_lower_point(Point<int32_t>(idb_core_rect->get_low_x(), idb_core_rect->get_low_y()));
  _contest_db->_ContestLayout->set_core_upper_point(Point<int32_t>(idb_core_rect->get_high_x(), idb_core_rect->get_high_y()));
}
void ContestWrapper::wrapContestRowList()
{
  // std::vector<std::vector<ContestRow*>> row_2d_list;
  // row_2d_list.resize(_idb_layout->get_rows()->get_row_num());
  // for (auto* pl_row : _idb_layout->get_rows()->get_row_list()) {
  //   auto* pl_site = pl_row->get_site();
  //   ContestSite* row_site = new ContestSite(pl_site->get_name());
  //   row_site->set_width(pl_site->get_width());
  //   row_site->set_height(pl_site->get_height());

  //   int32_t row_shift_x = pl_row->get_original_coordinate()->get_x() + _contest_db->_shift_x;
  //   int32_t row_shift_y = pl_row->get_original_coordinate()->get_y() + _contest_db->_shift_y;
  //   int32_t row_index = std::floor(static_cast<double>(row_shift_y) / pl_row->get_site()->get_width());
  //   ContestRow* row = new ContestRow(pl_row->get_name(), row_site, pl_row->get_site_count());
  //   row->set_coordinate(row_shift_x, row_shift_y);
  //   row->set_orient(pl_site->get_orient());
  //   row_2d_list.at(row_index).push_back(row);
  // }
  // _contest_db->get_ContestLayout()->set_row_2d_list(row_2d_list);
}
void ContestWrapper::completeConnection()
{
  for (auto pair : _contest_db->_ContestPin_map) {
    auto* pin = pair.first;
    auto* p_pin = pair.second;

    auto* inst = pin->get_instance();

    if (inst) {
      auto* p_inst = _contest_db->_ContestInstance_map[inst];

      p_pin->set_ContestInstance(p_inst);
      p_inst->add_pin(p_pin);  
    }

    auto* net = pin->get_net();
    auto* p_net = _contest_db->_ContestNet_map[net];

    p_pin->set_ContestNet(p_net);

    auto* driver_pin = net->get_driving_pin();
    if (driver_pin) {
      if (driver_pin->get_pin_name() == pin->get_pin_name()) {
        p_net->set_driver_pin(p_pin);
        if(p_net->isClockNet())
        {
          p_pin->set_pin_flag_type(ContestPIN_FALG_TYPE::kClockPin);
        }
      } else {
        p_net->add_sink_pin(p_pin);
      }
    } else {
      p_net->add_sink_pin(p_pin);
    }
  }
}


std::vector<ContestInstance*> ContestWrapper::obtianPlacableContestInstanceList()
{
  std::vector<ContestInstance*> placable_list;
  for (auto* p_inst : _contest_db->_ContestInstance_list) {
    if (p_inst->isFixed()) {
      continue;
    }
    placable_list.push_back(p_inst);
  }
  return placable_list;
}
bool ContestWrapper::isBoundaryCell(idb::IdbInstance* inst)
{

  Point<int32_t> die_lower = Point<int32_t>(_idb_layout->get_die()->get_llx(),_idb_layout->get_die()->get_lly());
  Point<int32_t> die_upper = Point<int32_t>(_idb_layout->get_die()->get_urx(),_idb_layout->get_die()->get_ury());;
  Point<int32_t> core_lower = Point<int32_t>(_idb_layout->get_core()->get_bounding_box()->get_low_point().get_x(),_idb_layout->get_core()->get_bounding_box()->get_low_point().get_y());
  Point<int32_t> core_upper = Point<int32_t>(_idb_layout->get_core()->get_bounding_box()->get_high_point().get_x(),_idb_layout->get_core()->get_bounding_box()->get_high_point().get_y());

  if ((inst->get_coordinate()->get_x() - inst->get_cell_master()->get_width() >= die_lower.get_x() && inst->get_coordinate()->get_x() + inst->get_cell_master()->get_width() <= core_lower.get_x())
      || (inst->get_coordinate()->get_x() - inst->get_cell_master()->get_width() >= core_upper.get_x() && inst->get_coordinate()->get_x() + inst->get_cell_master()->get_width() <= die_upper.get_x())
      || (inst->get_coordinate()->get_y() - inst->get_cell_master()->get_height() >= die_lower.get_y() && inst->get_coordinate()->get_y() + inst->get_cell_master()->get_height() <= core_lower.get_y())
      || (inst->get_coordinate()->get_y() - inst->get_cell_master()->get_height() >= core_upper.get_y() && inst->get_coordinate()->get_y() + inst->get_cell_master()->get_height() <= die_upper.get_y())) {
    return true;
  } else {
    return false;
  }
}

//debug
void ContestWrapper::printPostGlobalPlaceDatabase()
{
  // instance
  int32_t p_inst_nums = _contest_db->get_ContestInstance_pvec().size();
  // int32_t logic_inst_nums = 0;
  int32_t buffer_inst_nums = 0;
  int32_t flipflop_inst_nums = 0;
  int32_t macro_inst_nums = 0;
  // int32_t boundary_inst_nums = 0;
  int32_t instance_pin_nums = 0;

  int32_t fixed_inst_nums = 0;
  int32_t placeable_inst_nums = 0;
  int32_t instance_inputpin_nums = 0;
  int32_t instance_outpin_nums = 0;


  for(auto cell : _contest_db->get_ContestInstance_pvec())
  {
    if(cell->isFixed())
    {
      fixed_inst_nums++;
    }else if (cell->isPlaceable()){
      placeable_inst_nums++;
    }
    if(cell->isBuffer())
    {
      buffer_inst_nums++;
    }
    if(cell->isFlipflop())
    {
        flipflop_inst_nums++;
    }
    if(cell->isMacro())
    {
      macro_inst_nums++;
    }

    instance_pin_nums += cell->get_pin_vec().size();
    instance_inputpin_nums += cell->get_inpin_vec().size();
    instance_outpin_nums += cell->get_outpin_vec().size();
  }

  LOG_INFO << "PGPInstances Num : " << p_inst_nums;
  LOG_INFO << "1.Fixed PGPInstances Num : " << fixed_inst_nums;
  LOG_INFO << "2.Placeable PGPInstances Num : " << placeable_inst_nums;
  LOG_INFO << "Buffer Num : " << buffer_inst_nums;
  LOG_INFO << "FF Num : " << flipflop_inst_nums;
  LOG_INFO << "Block Num : " << macro_inst_nums;



  LOG_INFO << "Instances-Pin Num : " << instance_pin_nums;
  LOG_INFO << "Instances-InputPin Num : " << instance_inputpin_nums;
  LOG_INFO << "Instances-OutPin Num : " << instance_outpin_nums;

  // net
  int32_t p_net_nums = _contest_db->get_ContestNet_pvec().size();
  int32_t dont_care_net_nums = 0;
  int32_t driver_pin_num = 0;
  int32_t sink_pin_num = 0;
  int32_t total_net_pins_num = 0;



  for (auto p_net : _contest_db->get_ContestNet_pvec()) {
    if(p_net->get_driver_pin() != nullptr)
    {
      driver_pin_num++;
    }
    if(!p_net->get_sink_pins().empty())
    {
      for(auto sink : p_net->get_sink_pins())
      {
        sink_pin_num++;
      }
    }
    if(!p_net->get_pins().empty())
    {
      total_net_pins_num += p_net->get_pins().size();
    }
  }
    int32_t sum_pin = sink_pin_num + driver_pin_num;
  
  LOG_INFO << "PGPNet Num : " << p_net_nums;
  LOG_INFO << "DriverPin Num : " << driver_pin_num;
  LOG_INFO << "SinkPin Num : " << sink_pin_num;
  LOG_INFO << "DriverPin + SinkPin  Num : " << sum_pin;
  LOG_INFO << "Total Net-Pins Num : " << total_net_pins_num;

  // pin
  int32_t p_pin_nums = _contest_db->get_ContestPin_pvec().size();
  int32_t flipflopclk_pin_nums = 0;
  int32_t po_pin_nums = 0;
  int32_t pi_pin_nums = 0;
  int32_t pio_pin_nums = 0;
  int32_t instanceinput_pin_nums = 0;
  int32_t instanceoutput_pin_nums = 0;
  int32_t clock_pin_nums = 0;
  int32_t reset_pin_nums = 0;
  int32_t  NoFlagTypePin = 0;

  int32_t pin_instance_nums = 0;
  int32_t pin_net_nums = 0;
   bool   flag_intance = false;




  for (auto p_pin : _contest_db->get_ContestPin_pvec()) {
    if (p_pin->isFlipFlopClkPin()) {
      flipflopclk_pin_nums++;
    }
    if (p_pin->isPO()) {
      po_pin_nums++;
    }
    if (p_pin->isPI()) {
      pi_pin_nums++;
    }
    if(p_pin->isPIO())
    {
      pio_pin_nums++;
    }
    if (p_pin->isInstanceInputPin()) {
      instanceinput_pin_nums++;
    }
    if (p_pin->isInstanceOutputPin()) {
      instanceoutput_pin_nums++;
    }
    if(p_pin->isClockPin())
    {
        clock_pin_nums++;
    }
    if(p_pin->get_ContestNet() != nullptr)
    {
      pin_net_nums++;
    }

  }
  LOG_INFO << "PGPPin Num : " << p_pin_nums;
  LOG_INFO << "1.1 PO Num : " << po_pin_nums;
  LOG_INFO << "1.2 PI Num : " << pi_pin_nums;
  LOG_INFO << "1.3 PIO Num : " << pio_pin_nums;

  LOG_INFO << "2.1 InstanceInputPin Num : " << instanceinput_pin_nums;   
  LOG_INFO << "2.2 InstanceOutputPin Num : " << instanceoutput_pin_nums; 
  LOG_INFO << "3. FlipflopClk  Num : " << flipflopclk_pin_nums;
  LOG_INFO << "4. ClockPin  Num : " << clock_pin_nums;
  LOG_INFO << "5. ResetPin  Num : " << reset_pin_nums;
  LOG_INFO << "6. NoFlagTypePin  Num : " << NoFlagTypePin;

  LOG_INFO << "Pin-Instance Num : " << pin_instance_nums;
  LOG_INFO << "Pin-Net Num : " << pin_net_nums;
  LOG_INFO << "Flag : " << flag_intance;
}


IdbRow *ContestWrapper::findRow(int loc_y) {
  IdbRows *rows = _idb_layout->get_rows();

  for (auto row : rows->get_row_list()) {
    if (row->get_bounding_box()->get_low_y() == loc_y) {
      return row;
    }
  }
  return nullptr;
}










bool ContestWrapper::transfer_contest_to_idb()
{
  // auto idb_inst = _idb_design->get_instance_list()->find_instance("U117897");

  // idb_inst->set_status_placed();
  // idb_inst->set_coodinate(1, 1);

  // auto make_route = new MakeRoute(this*);
  // auto idb_pin_list = idb_inst->get_pin_list()->get_pin_list();
  // std::set<std::string> net_set;
  // for (auto idb_pin : idb_pin_list) {
  //   auto idb_net = idb_pin->get_net();
  //   if (idb_net != nullptr) {
  //     net_set.insert(idb_net->get_net_name());
  //   } // end if
  // } // end for


  // // std::map<std::string, ContestNet*> net_map;
  // std::vector<ContestNet>& contest_net_list = _data_manager->get_database()->get_net_list();
  // int net_num = contest_net_list.size();
  // for (int i = 0; i < net_num; i++) {
  // // for (auto net : _data_manager->get_database()->get_net_list()) {
  //   // net_map.insert(std::make_pair(net.get_net_name(), &net));
  //   auto net = contest_net_list[i];
  //   auto idb_net = _data_manager->get_idb_design()->get_net_list()->find_net(net.get_net_name());
  //   if (net_set.find(net.get_net_name()) != net_set.end()) {
  //     ContestNet contest_net;
  //     contest_net.set_net_name(idb_net->get_net_name());
  //     std::vector<ContestPin>& pin_list = contest_net.get_pin_list();
  //     for (idb::IdbPin* idb_pin : idb_net->get_instance_pin_list()->get_pin_list()) {
  //       ContestCoord coord(idb_pin->get_instance()->get_bounding_box()->get_middle_point_x(),
  //                         idb_pin->get_instance()->get_bounding_box()->get_middle_point_y(), 0);

  //       ContestPin contest_pin;
  //       contest_pin.set_real_coord(coord);
  //       contest_pin.set_grid_coord(getGCellCoord(coord));
  //       contest_pin.get_contained_instance_list().push_back(idb_pin->get_instance()->get_name());
  //       pin_list.push_back(contest_pin);
  //     }
  //     if (idb_net->get_io_pin() != nullptr) {
  //       idb::IdbPin* io_pin = idb_net->get_io_pin();
  //       ContestCoord coord(io_pin->get_bounding_box()->get_middle_point_x(), io_pin->get_bounding_box()->get_middle_point_y(), 0);

  //       ContestPin contest_pin;
  //       contest_pin.set_real_coord(coord);
  //       contest_pin.set_grid_coord(getGCellCoord(coord));
  //       contest_pin.get_contained_instance_list().push_back("io");
  //       pin_list.push_back(contest_pin);
  //     }
  //     make_route->doRoute(contest_net);
  //     contest_net_list[i] = contest_net;
  //   } // end if
  // } // end for

  return true;
}

}  // namespace ieda_contest
